
#include "IndexRecord.h"
#include "Record.h"
#include <iostream>
#include <string.h>


#define KEY 0
#define POINTER 1

int IndexRecord :: Compare (Attribute &lowVal, Attribute &highVal, Type &myType)
{
	switch(myType)
	{
		case Int:
			if( Record::GetInt( KEY ) < lowVal.GetInt() )
			{
				return -1;
			}
			else if (GetInt( KEY ) > highVal.GetInt() )
			{
				return 1;
			}
			else 
			{
				return 0;
			}
			break;
		case Double:
			if(GetDouble( KEY ) < lowVal.GetDouble() )
			{
				return -1;
			}
			else if (GetDouble( KEY ) > highVal.GetDouble() )
			{
				return 1;
			}
			else 
			{
				return 0;
			}
			break;
		case String:
			if( strcmp(GetString( KEY ), lowVal.GetString() ) < 0)
			{
				return -1;
			}
			else if( strcmp(GetString( KEY ), lowVal.GetString() ) > 0)
			{
				return 1;
			}
			else 
			{
				return 0;
			}
			break;
		default:
			std::cerr << "A bad type was given\n";
			return -1;	// return -1 just so we dont return a value that falls within the range
			break;
	}
}

void IndexRecord :: Load (char *key, int keyLen, int pointer)
{
	numAtts = 2;
	myData = new Attribute[numAtts];
	SetString(key, KEY);
	SetInt(pointer, POINTER);
}

int IndexRecord ::   GetPointer ()
{
	return GetInt( POINTER );
}

void IndexRecord:: GetKey (Attribute& at, Type &myType)
{
	
	switch(myType)
	{
		case Int:
			at.LoadInt(myData[KEY].GetInt());
			break;
		case Double:	
			at.LoadDouble(myData[KEY].GetDouble());
			break;
		case String:
			at.LoadString(myData[KEY].GetString());
			break;
		default:
			std::cerr << "A bad type was given\n";
			break;
	}
}

void IndexRecord:: ConsumeToIndexRecord(Record & rec, Schema & sch, 
	char* keyName, int pageID )
{
	int key_pos = sch.Find (keyName);
	Type type = sch.FindType ( key_pos );
	
	switch(type)
	{
		case Int:
		{
			int i = rec.GetInt(key_pos);
			int len = sizeof (int);
			char * data = new char[len];
			memmove (data, &i, len);
			Load( data, len, pageID );
			delete data;
			break;
		}
		case Double:
		{
			double d = rec.GetDouble(key_pos);
			int sz = sizeof(double);
			char * data = new char[sz];
			memmove (data, &d, sz);
			Load( data, sz, pageID );	
			delete data;
			break;
		}
		case String:
		{
			char* c = rec.GetString(key_pos);
			int len = strlen(c);
			Load( c, len, pageID );
			delete c;
			break;
		}
		default:
			std::cout<<"Bad type:"<<__LINE__<<std::endl;
			break;
	}
	
}
